// @Author miaoqing
// @Date 2024/03/04 14:02:00
// @Desc
package logic

import (
	"core/command"
	"core/common"
	"core/network"
	"sync"
)

var (
	ccMgr    *CenterClientMgr
	cMgrOnce sync.Once
)

type CenterClientMgr struct {
	clients *sync.Map
}

func centerClientMgrGetMe() *CenterClientMgr {
	cMgrOnce.Do(func() {
		ccMgr = &CenterClientMgr{
			clients: &sync.Map{},
		}
	})
	return ccMgr
}

func (mgr *CenterClientMgr) addCenterClient(srvID string, c *CenterClient) {
	if _, ok := mgr.clients.Load(srvID); ok {
		return
	}
	mgr.clients.Store(srvID, c)
}

func (mgr *CenterClientMgr) removeCenterClient(srvID string) {
	mgr.clients.Delete(srvID)
}

func (mgr *CenterClientMgr) discoveryCenterSrv() {
	resp := &common.GetAllServerInfoResp{}
	err := common.SendCenterHttpRequest(nil, resp, "GET", "/getCenterServer")
	if err != nil {
		return
	}
	mgr.clearInvalidCenterClient(resp.SInfos)
	for _, srv := range resp.SInfos {
		if _, ok := mgr.clients.Load(srv.ServerID); ok {
			continue
		}
		client := &CenterClient{
			tcpClient: network.NewTcpClient(16*1024, 16*1024),
			srvID:     srv.ServerID,
			srvAddr:   srv.Addr,
		}
		client.tcpClient.OnCloseCallBack = client.OnCloseCallBack
		mgr.addCenterClient(srv.ServerID, client)
	}
}

func (mgr *CenterClientMgr) clearInvalidCenterClient(services []*common.ServerInfo) {
	mgr.clients.Range(func(k, v interface{}) bool {
		client, ok := v.(*CenterClient)
		if ok {
			find := false
			for _, svcEntry := range services {
				//info := function.GetPerformanceData(svcEntry.Service.Tags[0])
				//if client.ZoneId == info.Zid && client.serverID == svcEntry.Service.ID {
				if client.srvID == svcEntry.ServerID {
					find = true
				}
			}
			if !find {
				mgr.clients.Delete(client.srvID)
			}
		}
		return true
	})
}

func (mgr *CenterClientMgr) checkConnect() {
	mgr.clients.Range(func(key, value any) bool {
		client := value.(*CenterClient)
		client.checkConnect(client.srvAddr)
		return true
	})
}

func (mgr *CenterClientMgr) centerClose() {
	mgr.clients = &sync.Map{}
}

func (mgr *CenterClientMgr) sendMsgToCenterMessageQueue(msg interface{}) bool {
	mgr.clients.Range(func(key, value any) bool {
		center, ok := value.(*CenterClient)
		if !ok {
			return true
		}
		return center.sendCenterMsg(command.CenterCommand_OnlineMsgToCenter_Center, msg)
	})
	return true
}
